#ifndef VECTOR_H
#define VECTOR_H

#include <math.h>

#define COMPARE_FLOAT(a,b) (fabs(a - b) < 0.0001)

struct Vector
{
	float x, y, z;

	Vector(){ x=0; y=0; z=0;};
	Vector(float xd, float yd, float zd){ x= xd; y= yd; z = zd; };
	Vector(float q){ x= q; y= q; z = q; };
	
	Vector& Vector::operator+=(const Vector &n)
	{
		x += n.x;
		y += n.y;
		z += n.z;

		return *this;
	}

	bool Vector::operator==(const Vector &n)
	{
		return COMPARE_FLOAT(x, n.x) && COMPARE_FLOAT(y, n.y) && COMPARE_FLOAT(z, n.z);
	}

	Vector& Vector::operator+=( float n )
	{
		x += n;
		y += n;
		z += n;

		return *this;
	}

	Vector& Vector::operator-=(const Vector &n)
	{
		x -= n.x;
		y -= n.y;
		z -= n.z;

		return *this;
	}

	Vector& Vector::operator-=(float n)
	{
		x -= n;
		y -= n;
		z -= n;

		return *this;
	}

	Vector& Vector::operator*=(const Vector &n)
	{
		x *= n.x;
		y *= n.y;
		z *= n.z;

		return *this;
	}

	Vector& Vector::operator*=(float n)
	{
		x *= n;
		y *= n;
		z *= n;

		return *this;
	}

	Vector& Vector::operator/=(const Vector &n)
	{
		x /= n.x;
		y /= n.y;
		z /= n.z;

		return *this;
	}

	Vector& Vector::operator/=(float n)
	{
		x /= n;
		y /= n;
		z /= n;

		return *this;
	}

	Vector Vector::operator%(int q)
	{
		Vector n = *this;
		n.x = (float)((int)x % q);
		n.y = (float)((int)y % q);
		n.z = (float)((int)z % q);

		return n;
	}

	const Vector Vector::operator+(const Vector &other) const {
		return Vector(*this) += other;
	}

	const Vector Vector::operator+( float other) const {
		return Vector(*this) += other;
	}

	const Vector Vector::operator*(const Vector &other) const {
		return Vector(*this) *= other;
	}

	const Vector Vector::operator*( float other) const {
		return Vector(*this) *= other;
	}

	const Vector Vector::operator/(const Vector &other) const {
		return Vector(*this) /= other;
	}

	const Vector Vector::operator/( float other) const {
		return Vector(*this) /= other;
	}

	const Vector Vector::operator-(const Vector &other) const {
		return Vector(*this) -= other;
	}

	const Vector Vector::operator-( float other) const {
		return Vector(*this) -= other;
	}

	Vector inProduct( const Vector &V2 ) const
	{
		return Vector(
			y * V2.z - z * V2.y,
			z * V2.x - x * V2.z,
			x * V2.y - y * V2.x
		);
	}

	Vector uitProduct( const Vector &V ) const
	{
		return Vector(
			y*V.z - z*V.y,
			z*V.x - x*V.z,
			x*V.y - y*V.x
		);
	}

	float dotProduct( const Vector &V ) const
	{
		return x*V.x + y*V.x + z*V.z; 
	}

	float Vector::length() const {

		return((float)sqrt(x*x + y*y + z*z));
	}

	Vector Vector::normalize() const {

		float len;

		Vector n = *this;

		len = length();
		if (len > 0) {
			n.x /= len;
			n.y /= len;
			n.z /= len;
		}

		return n;
	}

};

#define Position Vector
#define Dimensions Vector


#endif